﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using SdmxMl.Common;
using SdmxMl.GenericMetadata;
using SdmxMl.Structure;
using Telerik.WinControls;
using Telerik.WinControls.Data;
using Telerik.WinControls.UI;

namespace PluginMeb
{
    /// <summary> Helper for initializing and filling grid matrix. </summary>
    public class GridCreator
    {
        #region Constants

        public const string COL_KLASSE_CH = "KlasseCH";
        public const string COL_SCHULART = "Schulart";

        public const string COL_BJAHR_KT = "BJAHR_KT";
        public const string COL_BJAHR_CH = "BJAHR_CH";
        public const string COL_ES_VF = "ES_VF";
        public const string COL_ES_VT = "ES_VT";
        public const string COL_AGE_INF = "AGE_INF";
        public const string COL_AGE_SUP = "AGE_SUP";
        public const string COL_SCHUL_VF = "VF";
        public const string COL_SCHUL_VT = "VT";
        public const string COL_SCHUL_TEXT = "Text";
        public const string COL_COMMENT = "Comment";

        public const string ANNOT_S_VF = "Schulart_guAb";
        public const string ANNOT_S_VT = "Schulart_guBis";

        public const string STR_ZERO = "0";

        #endregion

        #region Internal Members

        private RadGridView gridView;
        private MatrixCache metaCache;
        private int selectedCantonIndex;
        private int ModifFlag;

        /// <summary>Grid Kombi managers</summary>
        private GridAusbild gridAusbildMgr;


        #endregion

        #region Properties

        public bool InEdition { get { return gridView.ReadOnly == false; } }

        #endregion

        #region EventsHandler

        public event EventHandler DataModified;

        public void RaiseDataModified(ModifType modif)
        {
            if (InEdition)
            {
                EventHandler eventHandler = this.DataModified;
                if (eventHandler != null)
                    this.DataModified(this, EventArgs.Empty);
                ModifFlag |= (int)modif;
            }
        }


        #endregion //EventsHandler

        #region Constructor

        public GridCreator(RadGridView gridControl, RadGridView gridKombi, MatrixCache cache)
        {
            gridView = gridControl;
            metaCache = cache;

            // Prepare ausbildung Kombi grid
            gridAusbildMgr = new GridAusbild(gridKombi, metaCache);

            // Set grid read only
            gridView.ReadOnly = gridAusbildMgr.gridView.ReadOnly = true;

            // Register event for attaching multicombo editor for KlasseCH code
            gridView.CellEditorInitialized += new GridViewCellEventHandler(this.CellEditorInitialized);

            // Register event for displaying additional info via tooltip
            gridView.ToolTipTextNeeded += new ToolTipTextNeededEventHandler(ToolTipTextNeeded);

            gridView.CellDoubleClick += new GridViewCellEventHandler(CellDoubleClick);

            // register row change for Ausbild Kombi update
            gridView.CurrentRowChanging += new CurrentRowChangingEventHandler(CurrentRowChanging);
            gridView.CurrentRowChanged += new CurrentRowChangedEventHandler(CurrentRowChanged);

            // Register cell change for dirty flag
            gridView.CellValueChanged += new GridViewCellEventHandler(CellValueChanged);

            gridView.RowsChanged += gridView_RowsChanged;
        }

        /// <summary>
        /// Event used to track move Row in matrix
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e">Type of row action</param>
        void gridView_RowsChanged(object sender, GridViewCollectionChangedEventArgs e)
        {
            if (gridView.ReadOnly  == false && e.Action == NotifyCollectionChangedAction.Move)
                RaiseDataModified(ModifType.Matrix); 
        }





        #endregion

        #region Grid Columns construction

        /// <summary>
        /// 
        /// </summary>
        public void CreateView()
        {
            CodeListType cltBildung = metaCache.CltKlasseCh;

            gridView.BeginUpdate();

            gridView.MasterTemplate.Columns.Clear();

            gridView.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
            gridView.EnableAlternatingRowColor = true;
            gridView.MasterTemplate.AllowColumnChooser = false;

            // Prepare columns
            GridViewDecimalColumn decimalColumn = new GridViewDecimalColumn(COL_SCHULART);
            decimalColumn.DecimalPlaces = 0;
            decimalColumn.Maximum = 99999999;
            decimalColumn.Width = 70;
            decimalColumn.AllowResize = false;
            decimalColumn.ReadOnly = true;
            gridView.MasterTemplate.Columns.Add(decimalColumn);

            // Valid From and Valid to associated to Schulart code (infotrmative columns)
            decimalColumn = new GridViewDecimalColumn(COL_SCHUL_VF);
            decimalColumn.DecimalPlaces = 0;
            decimalColumn.Maximum = 9999;
            decimalColumn.Width = 60;
            decimalColumn.AllowResize = false;
            decimalColumn.ReadOnly = true;
            gridView.MasterTemplate.Columns.Add(decimalColumn);

            decimalColumn = new GridViewDecimalColumn(COL_SCHUL_VT);
            decimalColumn.DecimalPlaces = 0;
            decimalColumn.Maximum = 9999;
            decimalColumn.Width = 60;
            decimalColumn.AllowResize = false;
            decimalColumn.ReadOnly = true;
            gridView.MasterTemplate.Columns.Add(decimalColumn);

            // Text associated to Schulart code (Informative column)
            GridViewTextBoxColumn colText = new GridViewTextBoxColumn(COL_SCHUL_TEXT);
            colText.ReadOnly = true;
            gridView.MasterTemplate.Columns.Add(colText);


            // Klasse CH (ex BildungsArt)
            GridViewMultiComboBoxColumn colBildung = new GridViewMultiComboBoxColumn();
            colBildung.DataSource = cltBildung.CodeList.GetTableRepresentation();
            colBildung.DisplayMember = "Code";
            colBildung.ValueMember = "Code";
            colBildung.FieldName = COL_KLASSE_CH;
            colBildung.HeaderText = COL_KLASSE_CH;
            colBildung.Width = 70;
            colBildung.AllowResize = false;
       //     colBildung.ReadOnly = isEditable == false;
            gridView.MasterTemplate.Columns.Add(colBildung);

            // BJAHR KT and CH
            decimalColumn = new GridViewDecimalColumn(COL_BJAHR_KT);
            decimalColumn.DecimalPlaces = 0;
            decimalColumn.Maximum = 100;
            decimalColumn.Width = 60;
            decimalColumn.AllowResize = false;

            gridView.MasterTemplate.Columns.Add(decimalColumn);

            decimalColumn = new GridViewDecimalColumn(COL_BJAHR_CH);
            decimalColumn.DecimalPlaces = 0;
            decimalColumn.Width = 60;
            decimalColumn.AllowResize = false;
            decimalColumn.Maximum = 100;
            gridView.MasterTemplate.Columns.Add(decimalColumn);

            // ES From to
            decimalColumn = new GridViewDecimalColumn(COL_ES_VF);
            decimalColumn.DecimalPlaces = 0;
            decimalColumn.Width = 60;
            decimalColumn.AllowResize = false;
            decimalColumn.Maximum = 9999;
            gridView.MasterTemplate.Columns.Add(decimalColumn);

            decimalColumn = new GridViewDecimalColumn(COL_ES_VT);
            decimalColumn.DecimalPlaces = 0;
            decimalColumn.Width = 60;
            decimalColumn.AllowResize = false;
            decimalColumn.Maximum = 9999;
            gridView.MasterTemplate.Columns.Add(decimalColumn);

            // AGE inf and sup
            decimalColumn = new GridViewDecimalColumn(COL_AGE_INF);
            decimalColumn.DecimalPlaces = 0;
            decimalColumn.Width = 60;
            decimalColumn.AllowResize = false;
            gridView.MasterTemplate.Columns.Add(decimalColumn);

            decimalColumn = new GridViewDecimalColumn(COL_AGE_SUP);
            decimalColumn.DecimalPlaces = 0;
            decimalColumn.Width = 60;
            decimalColumn.AllowResize = false;
            gridView.MasterTemplate.Columns.Add(decimalColumn);

            colText = new GridViewTextBoxColumn(COL_COMMENT);
            gridView.MasterTemplate.Columns.Add(colText);

            gridView.EndUpdate();

        }

        #endregion

        #region Cell editor Initialized event

        /// <summary>Format multicombo for nice presentation</summary>
        /// <param name="sender"></param><param name="e"></param>
        private void CellEditorInitialized(object sender, GridViewCellEventArgs e)
        {
            RadMultiColumnComboBoxElement multiComboElement = gridView.ActiveEditor as RadMultiColumnComboBoxElement;
            if (multiComboElement != null)
            {
                multiComboElement.DropDownStyle = RadDropDownStyle.DropDown;
                multiComboElement.EditorControl.Columns[0].Width = 80;
                MultiColumnComboGridView mgv = multiComboElement.EditorControl as MultiColumnComboGridView;
                if (mgv != null)
                {
                    multiComboElement.AutoFilter = true;
                    if (multiComboElement.EditorControl.MasterTemplate.FilterDescriptors.Count == 0)
                    {
                        multiComboElement.EditorControl.FilterDescriptors.Add(multiComboElement.DisplayMember, FilterOperator.StartsWith, String.Empty);
                    }
                }

                multiComboElement.EditorControl.Columns[1].Width = 292;

                multiComboElement.PopupOpening += new CancelEventHandler(multiComboElement_PopupOpening);
            }
        }

        /// <summary>Resize multicombo editor </summary>
        /// <param name="sender"></param> <param name="e"></param>
        void multiComboElement_PopupOpening(object sender, CancelEventArgs e)
        {
            RadMultiColumnComboBoxElement element = sender as RadMultiColumnComboBoxElement;
            element.MultiColumnPopupForm.MinimumSize = new Size(410, 250);
            element.EditorControl.GridViewElement.MinSize = new Size(410, 250);
        }
        #endregion

        #region Cell double click

        // Raise Schulart editor 
        private void CellDoubleClick(object sender, GridViewCellEventArgs e)
        {
            try
            {
                SchulartEdit(false);
            }
            catch { }
        }

        #endregion

        #region Row change Event

        /// <summary> Update Kombi table according to selected schulart </summary>
        /// <param name="sender"></param> <param name="e"></param>
        private void CurrentRowChanged(object sender, CurrentRowChangedEventArgs e)
        {
            // Get schulart code, add canton
            if (gridAusbildMgr != null && e.CurrentRow != null && e.CurrentRow is GridViewDataRowInfo
                && selectedCantonIndex >= 0
                && e.CurrentRow.Cells[COL_SCHULART].Value != null)
            {
                string fullCode = SchulartFullCode(
                    e.CurrentRow.Cells[COL_SCHULART].Value.ToString(), selectedCantonIndex);
                gridAusbildMgr.RefreshKombi(fullCode);
            }
        }

        private void CurrentRowChanging(object sender, CurrentRowChangingEventArgs e)
        {
            // Get schulart code, add canton
            if (gridView.ReadOnly == false
                && e.CurrentRow is GridViewDataRowInfo
                && selectedCantonIndex >= 0
                && e.CurrentRow.Cells[COL_SCHULART].Value != null)
            {
                string fullCode = SchulartFullCode(
                    e.CurrentRow.Cells[COL_SCHULART].Value.ToString(), selectedCantonIndex);

                if (gridAusbildMgr.SetKombiForSchulart(fullCode))
                    RaiseDataModified(ModifType.Kombi);
            }
        }
        #endregion

        #region Cell Value changed

        /// <summary>Cell value changed event. Set dirty flag </summary>
        /// <param name="sender"></param><param name="e"></param>
        private void CellValueChanged(object sender, GridViewCellEventArgs e)
        {
            RaiseDataModified(ModifType.Matrix);
        }

        #endregion

        #region Schulart Edition

        /// <summary>
        /// Modify Schulart properties or create new Schulart
        /// </summary>
        /// <param name="createNew">If True create new Schulart</param>
        public void SchulartEdit(bool createNew)
        {
            CodeType c = null;
            if (createNew)
            {
                // Creates a dummy code that held only canton information
                c = new CodeType();
                c.Id = string.Format("_{0}", selectedCantonIndex.ToString().PadLeft(2, '0'));
                // and edit
                DlgSchulart aDlg = new DlgSchulart(c, metaCache.CltSchulart, InEdition);
                if (aDlg.ShowDialog() == DialogResult.OK)
                {
                    // Add created code?
                    metaCache.CltSchulart.CodeList.Add(c);

                    // Creates a row for matrix
                    string vf, vt, text;
                    FetchSchulartDetail(c, out vf, out vt, out text);

                    GridViewDataRowInfo row = new GridViewDataRowInfo(gridView.MasterView);
                    string schulart = SchulartSimpleCode(c.Id);
                    object [] arr = new object[] { schulart, vf, vt, text,
                        string.Empty, STR_ZERO,STR_ZERO,null, null, STR_ZERO, STR_ZERO
                    };
                    for (int i = 0; i < arr.Length; i++)
                        row.Cells[i].Value = arr[i];

                    InsertOrdered( Convert.ToInt32(schulart), row);

                    RaiseDataModified(ModifType.Schulart);
                    RaiseDataModified(ModifType.Matrix);
                }
            }
            else // Modify parameters or delete Schulart
            {
                if (gridView.CurrentRow is GridViewDataRowInfo)
                {
                    object value = gridView.CurrentRow.Cells[GridCreator.COL_SCHULART].Value;
                    if (value != null)
                    {
                        string fullCode = GridCreator.SchulartFullCode(value.ToString(), selectedCantonIndex);
                        CodeType item = metaCache.CltSchulart.CodeList.LocateItem(fullCode) as CodeType;
                        if (item != null)
                        {
                            DlgSchulart aDlg = new DlgSchulart(item, metaCache.CltSchulart, InEdition);
                            DialogResult dlgResult = aDlg.ShowDialog();
                            if (dlgResult == DialogResult.OK)
                            {
                                //Reflects info validity and name if in edition
                                if (InEdition)
                                {
                                    // Scan all lines if code match, update info fields
                                    UpdateSchulartInfoInGrid(item);
 
                                    RaiseDataModified(ModifType.Schulart);
                                }
                            }
                                // Schulart erase
                            else if (dlgResult == DialogResult.Yes && InEdition)
                            {
                                // No more in codelist
                                metaCache.CltSchulart.CodeList.Remove(item);
                                RaiseDataModified(ModifType.Schulart);

                                // no more in matrix
                                DeleteSchulartInGrid(item);
                                RaiseDataModified(ModifType.Matrix);

                                // no more in Kombi hierarchy
                                gridAusbildMgr.EraseKombi(item.Id);
                                RaiseDataModified(ModifType.Kombi);
                            }
                        }
                    }
                }
            }

        }

        /// <summary>Helper to retrieve Schulart parameters from Schulart code</summary>
        /// <param name="item">The Schulart code</param>
        /// <param name="vf">Valid from info in code annotations</param>
        /// <param name="vt">Valid to info in code annotations</param>
        /// <param name="text">Code text in current language</param>
        private void FetchSchulartDetail(ISdmxHierarchyListItem item, out string vf, out string vt, out string text)
        {
            text = item.Name.ToString();
            vf = null;
            Annotation a = item.AnnotationList.GetAnnotationType(ANNOT_S_VF);
            if (a != null && a.Title.Length > 0)
                vf = a.Title;

            vt = null;
            a = item.AnnotationList.GetAnnotationType(ANNOT_S_VT);
            if (a != null && a.Title.Length > 0)
                vt = a.Title;
        }

        /// <summary>
        /// Update grid cells holding Schulart detail found in code
        /// </summary>
        /// <param name="item">chulart code</param>
        private void UpdateSchulartInfoInGrid(CodeType item)
        {
            foreach (GridViewRowInfo row in gridView.MasterTemplate.Rows)
            {
                if (item.Id == SchulartFullCode(row.Cells[COL_SCHULART].Value.ToString(), selectedCantonIndex))
                {
                    string vf, vt, text;
                    FetchSchulartDetail(item, out vf, out vt, out text);

                    row.Cells[COL_SCHUL_VF].Value = vf;
                    row.Cells[COL_SCHUL_VT].Value = vt;
                    row.Cells[COL_SCHUL_TEXT].Value = text;
                }
            }
        }

        /// <summary>
        /// Delete all rows holding specified Schulart code informtion
        /// </summary>
        /// <param name="item">Schulart code</param>
        private void DeleteSchulartInGrid(CodeType item)
        {
            List<GridViewRowInfo> deleteList = new List<GridViewRowInfo>();
            foreach (GridViewRowInfo row in gridView.MasterTemplate.Rows)
            {
                if (item.Id == SchulartFullCode(row.Cells[COL_SCHULART].Value.ToString(), selectedCantonIndex))
                    deleteList.Add(row);
            }
            foreach (GridViewRowInfo row in deleteList)
                gridView.MasterTemplate.Rows.Remove(row);
        }


        #endregion

        #region Grid Tooltip event

        /// <summary>Provides Tooltip for coded columns</summary>
        /// <param name="sender"></param> <param name="e"></param>
        private void ToolTipTextNeeded(object sender, ToolTipTextNeededEventArgs e)
        {
            GridDataCellElement dataCell = sender as GridDataCellElement;
            if (dataCell != null && dataCell.ColumnInfo.Name == GridCreator.COL_KLASSE_CH && dataCell.Value != null)
            {

                ISdmxHierarchyListItem item = metaCache.CltKlasseCh.CodeList.LocateItem(dataCell.Value.ToString());
                if (item != null)
                    e.ToolTipText = item.Name.ToString();
            }
            else if (dataCell != null && dataCell.ColumnInfo.Name == GridCreator.COL_SCHULART && dataCell.Value != null)
            {

                ISdmxHierarchyListItem item = metaCache.CltSchulart.CodeList.LocateItem(
                    SchulartFullCode(dataCell.Value.ToString(), selectedCantonIndex));
                if (item != null)
                    e.ToolTipText = item.Name.ToString();
            }
        }
        #endregion

        #region Code formatting helper

        /// <summary> Compose schulart code with associated canton </summary>
        /// <param name="schulart">base code</param>
        /// <param name="selectedCantonIndex">Associated canton</param>
        /// <returns>code with canton code added at end</returns>
        public static string SchulartFullCode(string schulart, int selectedCantonIndex)
        {
            return string.Format("{0}{1}", schulart, SchulartFullCodeTerminator(selectedCantonIndex));
        }

        public static string SchulartSimpleCode(string schulartFullCode)
        {
            return schulartFullCode.Length > 3 ? schulartFullCode.Substring(0, schulartFullCode.Length - 3) : string.Empty;
        }

        public static string SchulartFullCodeTerminator(int selectedCantonIndex)
        {
            return string.Format("_{0}", selectedCantonIndex.ToString().PadLeft(2, '0'));
        }
        #endregion

        #region Data binding

        /// <summary> Fill grid with matrix data for specified canton </summary>
        /// <param name="cantonIndex">targeted canton index</param>
        public void LoadUnboundData(int cantonIndex)
        {
            // Get matrix content for selected canton
            MetadataSetType metaSet = metaCache.GetMatrix(cantonIndex);
            selectedCantonIndex = cantonIndex;

            // Fill Grid with content
            Dictionary<string, ISdmxHierarchyListItem> dicoCodes = new Dictionary<string, ISdmxHierarchyListItem>();
            using (gridView.DeferRefresh())
            {
                gridView.MasterTemplate.Rows.Clear();

                // Iterates matrix rows
                foreach (AttributeValueSetType atv in metaSet.AttributeValueSetList)
                {
                    // Optimize code access
                    string schulart = atv.TargetValuesTypeList[ImportMetasetFromExcel.KEY_SCHULART];
                    ISdmxHierarchyListItem item = null;
                    if (dicoCodes.ContainsKey(schulart) == false)
                    {
                        item = metaCache.CltSchulart.CodeList.LocateItem(SchulartFullCode(schulart, selectedCantonIndex));
                        if (item != null)
                            dicoCodes.Add(schulart, item);
                    }
                    else
                    {
                        item = dicoCodes[schulart];
                    }

                    // if matrix code exists in Schulart, create row
                    if (item != null)
                    {
                        string vf, vt, text;
                        FetchSchulartDetail(item, out vf, out vt, out text);

                        // IN MSD KlasseCH is defined as BILDUNGSART
                        gridView.MasterTemplate.Rows.Add(schulart, vf, vt, text,
                            GetValue(atv, ImportMetasetFromExcel.KEY_KLASSE_CH, string.Empty),
                            GetValue(atv, ImportMetasetFromExcel.KEY_BILDUNG_KT, STR_ZERO),
                            GetValue(atv, ImportMetasetFromExcel.KEY_BILDUNG_CH, STR_ZERO),
                            GetValue(atv, ImportMetasetFromExcel.KEY_GULT_AB, null),
                            GetValue(atv, ImportMetasetFromExcel.KEY_GULT_BIS, null),
                            GetValue(atv, ImportMetasetFromExcel.KEY_ALTER_MIN, STR_ZERO),
                            GetValue(atv, ImportMetasetFromExcel.KEY_ALTER_MAX, STR_ZERO),
                            GetReportedAttribute(atv, ImportMetasetFromExcel.REPORT_COMMENT)
                            );
                    }
                }
            }

        }

        /// <summary>Get grid value to place according to matrix attribute info </summary>
        /// <param name="atv">matrix row attributes</param>
        /// <param name="keyId">attribute key</param>
        /// <param name="defaultVal">default value, if value not set in matrix row</param>
        /// <returns>value to place in grid cell</returns>
        private string GetValue(AttributeValueSetType atv, string keyId, string defaultVal)
        {
            string val = atv.TargetValuesTypeList[keyId];
            return val.Length == 0 || val == ImportMetasetFromExcel.EMPTY_MARKER ? defaultVal : val;
        }

        private string GetReportedAttribute(AttributeValueSetType atv, string conceptId)
        {
            string val = string.Empty;
            ReportedAttributeType r = atv.ReportedAttributeList.GetReportedAttributeOfConcept(conceptId);
            if (r != null)
                val = r.Value.ToString();
            if (val == ImportMetasetFromExcel.EMPTY_MARKER)
                val = string.Empty;
            return val;
        }

        /// <summary>refresh grid text according to language update</summary>
        public void UpdateLanguage()
        {
            // Update Ausbildung Kombi headers
            gridAusbildMgr.UpdateLanguage();

            // Update schulart text
            foreach (GridViewRowInfo row in gridView.MasterTemplate.Rows)
            {
                ISdmxHierarchyListItem item = metaCache.CltSchulart.CodeList.LocateItem(
                    SchulartFullCode(row.Cells[GridCreator.COL_SCHULART].Value.ToString(), selectedCantonIndex));
                row.Cells[GridCreator.COL_SCHUL_TEXT].Value = item.Name.ToString();
            }
        }


        #endregion

        #region Matrix Updating

        private MetadataSetType GetUpdatedMatrix()
        {

            FillMetaset fillMeta = new FillMetaset();
            return fillMeta.PersistGridToSdmx(selectedCantonIndex, gridView, metaCache.AgencyId);
        }

        #endregion

        #region Start / Save Cancel Edition

        public void TerminateCellEdition()
        {
            // Ensure current cell edition saved
            gridView.BeginUpdate();
            gridView.EndUpdate(true);

            gridAusbildMgr.gridView.BeginUpdate();
            gridAusbildMgr.gridView.EndUpdate(true);

            CurrentRowChanging(gridView, new CurrentRowChangingEventArgs(gridView.CurrentRow, gridView.CurrentRow));
        }

        /// <summary>Save edited metadata </summary>
        public void Save()
        {
            // Set grid read only
            gridView.AllowRowReorder = false;
            gridView.ReadOnly = gridAusbildMgr.gridView.ReadOnly = true;

            // Save matrix if modified
            if ((ModifFlag & (int)ModifType.Matrix) != 0)
                metaCache.UpdateMatrixContent(selectedCantonIndex, GetUpdatedMatrix());
            
            metaCache.Save(selectedCantonIndex, ModifFlag);
        }

        /// <summary>Start Edition metadata </summary>
        public void StartEdition()
        {
            ModifFlag = 0;
            // reserve in cache, if updated, refresh grid
            if (metaCache.Reserve(selectedCantonIndex))
                LoadUnboundData(selectedCantonIndex);

            // set Grids editable
            gridView.ReadOnly = gridAusbildMgr.gridView.ReadOnly = false;
            if (gridView.CurrentRow == null && gridView.Rows.Count > 0)
                gridView.CurrentRow = gridView.Rows[0];
            gridView.AllowRowReorder = true;
        }

        /// <summary>Cancel modifications & reload original </summary>
        public void CancelEdition(bool reload)
        {
            // Set grid read only
            gridView.AllowRowReorder = false;
            gridView.ReadOnly = gridAusbildMgr.gridView.ReadOnly = true;

           // Cancel reservation
            metaCache.CancelMatrixReservation();

           // Reload dirty one
            if (reload)
                metaCache.ReloadEditableContent(selectedCantonIndex, ModifFlag);
        }
        #endregion

        #region Add Schulart Row

        /// <summary> Get all Codes of schulart concerning current canton matrix </summary>
        /// <returns>The list of Schulart codes matching canton</returns>
        private List<CodeType> GetSchulartList()
        {
            List<CodeType> list = new List<CodeType>();
            foreach (CodeType c in metaCache.CltSchulart.CodeList)
            {
                if (c.Id.EndsWith(SchulartFullCodeTerminator(selectedCantonIndex)))
                    list.Add(c);
            }
            return list;
        }

        private void InsertOrdered(int schulartCode, GridViewDataRowInfo row)
        {
            // Scan rows to locate where to insert
            bool inserted = false;
            foreach (GridViewRowInfo gridRow in gridView.MasterTemplate.Rows)
            {
                int valcode = Convert.ToInt32(gridRow.Cells[COL_SCHULART].Value);
                if (valcode > schulartCode)
                {
                    gridView.Rows.Insert(gridRow.Index, row);
                    inserted = true;
                    break;
                }
            }
            // Not found, add at end
            if (inserted == false)
                gridView.Rows.Add(row);

            gridView.CurrentRow = row;
        }

        /// <summary>
        /// Add Row in matrix, using User Schulart selection
        /// </summary>
        public void AddRow()
        {
            if (InEdition)
            {
                // User dialog to select a Schulart associated to matrix canton
                DlgAddRow aDlg = new DlgAddRow(GetSchulartList());
                if (aDlg.ShowDialog(gridView) == DialogResult.OK)
                {
                    if (aDlg.SchulartFullCode != null)
                    {
                        GridViewDataRowInfo row = new GridViewDataRowInfo(gridView.MasterView);
                        string schulart = SchulartSimpleCode(aDlg.SchulartFullCode.Id);
                        int addCode =  Convert.ToInt32(schulart);

                        // Fetch Schulart properties to add in Grid row
                        string vf, vt, text;
                        FetchSchulartDetail(aDlg.SchulartFullCode, out vf, out vt, out text);
                        row.Cells[COL_SCHULART].Value = schulart;
                        row.Cells[COL_SCHUL_VF].Value = vf;
                        row.Cells[COL_SCHUL_VT].Value = vt;
                        row.Cells[COL_SCHUL_TEXT].Value = text;

                        InsertOrdered(addCode, row);

                        RaiseDataModified(ModifType.Matrix);
                    }
                }
            }
        }
        #endregion

        #region Row Duplicate

        /// <summary> Duplicate row that is currently selected </summary>
        /// <returns>True if operation success</returns>
        public bool RowDuplicate()
        {
            bool modified = false;

            if (gridView.CurrentRow != null && gridView.CurrentRow is GridViewDataRowInfo)
            {
                object value = gridView.CurrentRow.Cells[GridCreator.COL_SCHULART].Value;
                if (value != null)
                {
                    GridViewRowInfo curRow = gridView.CurrentRow;
                    GridViewDataRowInfo dataRowInfo = new GridViewDataRowInfo(gridView.MasterView);
                    // Request Jan 2014 Copy full content
                    //for (int i = 0; i < dataRowInfo.Cells.Count; ++i)
                    //{
                    //    dataRowInfo.Cells[i].Value = gridView.CurrentRow.Cells[i].Value;
                    //}
                    dataRowInfo.Cells[COL_SCHULART].Value = gridView.CurrentRow.Cells[COL_SCHULART].Value;
                    dataRowInfo.Cells[COL_SCHUL_VF].Value = gridView.CurrentRow.Cells[COL_SCHUL_VF].Value;
                    dataRowInfo.Cells[COL_SCHUL_VT].Value = gridView.CurrentRow.Cells[COL_SCHUL_VT].Value;
                    dataRowInfo.Cells[COL_SCHUL_TEXT].Value = gridView.CurrentRow.Cells[COL_SCHUL_TEXT].Value;
                    dataRowInfo.Cells[COL_KLASSE_CH].Value = gridView.CurrentRow.Cells[COL_KLASSE_CH].Value;
                    dataRowInfo.Cells[COL_ES_VF].Value = gridView.CurrentRow.Cells[COL_ES_VF].Value;
                    dataRowInfo.Cells[COL_ES_VT].Value = gridView.CurrentRow.Cells[COL_ES_VT].Value;

                    gridView.Rows.Insert(gridView.CurrentRow.Index+1, dataRowInfo);
                    gridView.CurrentRow = dataRowInfo;
                    modified = true;
                    
                    RaiseDataModified(ModifType.Matrix);
                }
            }
            return modified;
        }

        #endregion

        #region Row Erase

        public void EraseCurrentRow()
        {
            if (gridView.CurrentRow is GridViewDataRowInfo)
            {
                gridView.Rows.Remove(gridView.CurrentRow);
                RaiseDataModified(ModifType.Matrix);
            }
        }

        #endregion
    }
    


    
}
